package com.grgbanking.it.project.service.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.grgbanking.it.base.WXConnectionService;
import com.grgbanking.it.common.Constant;
import com.grgbanking.it.common.entity.GridExportParam;
import com.grgbanking.it.common.entity.PageQuery;
import com.grgbanking.it.common.json.JSONHelper;
import com.grgbanking.it.common.mail.MailUtil;
import com.grgbanking.it.common.util.Converter;
import com.grgbanking.it.common.util.DateUtil;
import com.grgbanking.it.common.util.HibernateUtil;
import com.grgbanking.it.common.util.PhoneMessageUtil;
import com.grgbanking.it.common.util.poi.POICreator;
import com.grgbanking.it.common.util.poi.POIShellContructor;
import com.grgbanking.it.external.entity.SupplierMsn;
import com.grgbanking.it.project.component.WXOperationWorkMessageCreator;
import com.grgbanking.it.project.dao.IOperationWorkDao;
import com.grgbanking.it.project.dao.IOperationWorkHandleDao;
import com.grgbanking.it.project.entity.OperationWork;
import com.grgbanking.it.project.entity.OperationWorkHandle;
import com.grgbanking.it.project.service.IOperationWorkService;
import com.grgbanking.it.system.dao.IDepartmentDao;
import com.grgbanking.it.system.dao.IEquipmentDao;
import com.grgbanking.it.system.dao.IUserDao;
import com.grgbanking.it.system.entity.Department;
import com.grgbanking.it.system.entity.GrgemEquipments;
import com.grgbanking.it.system.entity.User;
import com.grgbanking.it.wx.entity.WXVerify;


/**
 * 运维工作
 * 
 * OperationWorkService
 * 
 * @author 潘广伟
 * @Email p_3er@qq.com
 * @Date 2014-12-26 上午11:06:52
 * 
 * @version 1.0.0
 *
 */
@Service
public class OperationWorkService extends WXConnectionService implements IOperationWorkService {
	
	@Autowired
	private IOperationWorkDao<OperationWork, Integer> operationWorkDao;
	@Autowired
	private IOperationWorkHandleDao<OperationWorkHandle, Integer> operationWorkHandleDao;
	@Autowired
	private IUserDao<User, Integer> userDao;
	@Autowired
	private IDepartmentDao<Department, Integer> departmentDao;
	@Autowired
	private IEquipmentDao<GrgemEquipments, String> equipmentDao;
	@Autowired
	private WXOperationWorkMessageCreator messageCreator;
	@Autowired
	private POICreator poiCreator;
	
	@PostConstruct
	public void initMessageCreator() {
		super.setMessageCreator(messageCreator);
	}
	
	@Override
	public void saveOrUpdate(OperationWork operationWork) throws Exception {
		if(operationWork.getWorkOrigin().equals("OA")){
			operationWork.setStartTime(DateUtil.getInstance().todayShort());
		}else if(operationWork.getWorkOrigin().equals("微信")){
			User user = userDao.getUserByUserId(operationWork.getUsername());
			Department department = departmentDao.findById(user.getDeptId());
			operationWork.setGrade(2);
			operationWork.setTrueName(user.getUserName());
			operationWork.setPhone(user.getMobilNo());
			operationWork.setCreator(user.getUserId());
			operationWork.setEmail(user.getEmail());
			operationWork.setDepartmentId(department.getDeptId().toString());
			operationWork.setDepartmentName(department.getLongDeptname());
			operationWork.setStartTime(DateUtil.getInstance().todayShort());
		}
		
		operationWork.setState(1);
		operationWorkDao.saveOrUpdate(operationWork);
		if(operationWork.getMsgType() == 1){
			PhoneMessageUtil.getInstance().sentWhenWorkCreated(operationWork.getPhone());
		}else if(operationWork.getMsgType() == 2){
			MailUtil.getInstance().sentWhenWorkCreated(operationWork.getEmail());
		}else if(operationWork.getMsgType() == 3){
			messageCreator.sentWhenWorkFromCode(operationWork.getUsername());
		}
		
		messageCreator.sentForDistribute("lqhui1");
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public String findByPageToJson(PageQuery query,OperationWork operationWork,User user) throws Exception {
		StringBuffer hql = createQueryHQL(operationWork, user);
		System.out.println(hql);
		hql.append(" order by work.").append(query.getOrder().get("property")).append(" ").append(query.getOrder().get("direction"));

		List<OperationWork> list = HibernateUtil.listWithLazyData(operationWorkDao.pageByHQL(hql.toString(), query.getStart(), query.getLimit()), OperationWork.class);
		return JSONHelper.convertToGrid(operationWorkDao.getTotalByHQL(hql.toString()), list);
	}
	/**
	 * 获取HQL
	 * createQueryHQL
	 * 
	 * @param operationWork
	 * @param user
	 * @return
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	private StringBuffer createQueryHQL(OperationWork operationWork, User user)
			throws Exception {
		String username = operationWork.getUsername();
		operationWork.setUsername(null);

		StringBuffer hql = new StringBuffer("from OperationWork as work where ");
		hql.append(HibernateUtil.createConditionHQL(operationWork,"work","operationWorkHandles","workOrigins","states","startDate","endDate"));
		hql.append(createConditionHQL(user, username, operationWork.getStates()));
		hql.append(HibernateUtil.createDateCompareHQL("work.startTime",operationWork.getStartDate(), operationWork.getEndDate()));
		if(operationWork.getWorkOrigins() != null && operationWork.getWorkOrigins().length > 0){
			hql.append(HibernateUtil.convertToIN(operationWork.getWorkOrigins(), "work.workOrigin"));
		}
		hql.append(" and work.state<>0");
		return hql;
	}

	
	
	@Override
	public void delete(User user,Integer id) throws Exception {
		OperationWork work = operationWorkDao.findById(id);
		if(!user.getUserId().equals(work.getCreator()) 
				&& user.getAuthority().isPersonal(Constant.MODULE_OPERATION_WORK)){
			throw new Exception("你没有权限删除此记录！");
		}
		if(work.getState() != 1){
			throw new Exception("状态不是未处理，不能被删除！");
		}
		
		work.setState(0);
		operationWorkDao.update(work);
	}
	
	@Override
	public String findByIdToJson(Integer id) throws Exception {
		OperationWork operationWork = (OperationWork) HibernateUtil.loadLazyData(operationWorkDao.findById(id), OperationWork.class);
		return JSONHelper.convertObjectForForm(operationWork);
	}
	
	@Override
	public void updateForDistribute(Integer workId,String handlerJson) throws Exception{
		OperationWork work = operationWorkDao.findById(workId);
		StringBuffer handlers = new StringBuffer();
		JSONArray jsArray = JSONArray.fromObject(handlerJson);
		for (int i = 0; i < jsArray.size(); i++) {
            JSONObject obj = (JSONObject) jsArray.get(i);
            
            User handler = userDao.getUserByUserId(obj.getString("username"));
            
            OperationWorkHandle handle = distribute(work, handler);
            
            handlers.append(handle.getTrueName()).append(";");

    		PhoneMessageUtil.getInstance().sentToEngineer(handler.getMobilNo(), work);
    		
    		messageCreator.sentToEngineerWhenWorkDistribute(handler.getUserId(), work);
    		
    		messageCreator.sentToUserWhenWorkDistribute(work.getUsername(), handler);
		}
		
		if(handlers.length() > 0){
			work.setHandlers(handlers.toString());
			work.setState(2);
			operationWorkDao.update(work);
		}
		
	}
	/**
	 * 分配工作
	 * updateForDistribute
	 * 
	 * @param workId
	 * @param engineers
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public void updateForDistribute(Integer workId,String[] engineers) throws Exception{
		
		OperationWork work = operationWorkDao.findById(workId);
		StringBuffer handlers = new StringBuffer();

		for (String engineer : engineers) {
			if(StringUtils.isNotEmpty(engineer)){
				User handler = userDao.getUserByUserId(engineer);
				
	            OperationWorkHandle handle = distribute(work, handler);
	            
	            handlers.append(handle.getTrueName()).append(";");
	            
	    		PhoneMessageUtil.getInstance().sentToEngineer(handler.getMobilNo(), work);
	    		messageCreator.sentToEngineerWhenWorkDistribute(engineer, work);
	    		
	    		messageCreator.sentToUserWhenWorkDistribute(work.getUsername(), handler);
	    		
			}
		}
		
		if(handlers.length() > 0){
			work.setHandlers(handlers.toString());
			work.setState(2);
			operationWorkDao.update(work);
		}
	}
	/**
	 * 分配工作
	 * distribute
	 * 
	 * @param work
	 * @param user
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	private OperationWorkHandle distribute(OperationWork work, User user) {
		OperationWorkHandle handle = new OperationWorkHandle();
		handle.setOperationWork(work);
		handle.setUsername(user.getUserId());
		handle.setTrueName(user.getUserName());
		handle.setPhone(user.getMobilNo());
		handle.setState(2);
		operationWorkHandleDao.save(handle);
		return handle;
	}
	
	@Override
	public String findHandleToJson(Integer workId) throws Exception {
		List<OperationWorkHandle> list = HibernateUtil.listWithLazyData(operationWorkHandleDao.findByWorkId(workId),OperationWorkHandle.class);
		return JSONHelper.convertObjectForForm(list);
	}
	
	@Override
	public void updateForHandle(Integer workId,String describe,OperationWorkHandle handle, User handler) throws Exception{
		OperationWork work = operationWorkDao.findById(workId);
		OperationWorkHandle nowHandle = operationWorkHandleDao.findToHandle(workId, handler.getUserId(), 2,3); //正在处理或挂起的明细

		User shiftHandler = userDao.getUserByUserId(handle.getUsername());
		handle.setUsername(null);
		handle.setTrueName(null);
		
		if(StringUtils.isEmpty(handle.getHandleTime())){
			handle.setHandleTime(DateUtil.getInstance().todayShort());
		}
		
		if(work!= null && nowHandle != null){
			
			if(StringUtils.isNotEmpty(describe)){
				//更新工作描述信息
				work.setDescribe(describe);
			}
			Converter.convert(nowHandle, handle);
			operationWorkHandleDao.update(nowHandle);
			if(handle.getState() == 1){
				//转移
				OperationWorkHandle shiftHandle = new OperationWorkHandle();
				shiftHandle.setOperationWork(work);
				shiftHandle.setUsername(shiftHandler.getUserId());
				shiftHandle.setTrueName(shiftHandler.getUserName());
				shiftHandle.setUpTrueName(nowHandle.getTrueName());
				shiftHandle.setUpUsername(nowHandle.getUsername());
				shiftHandle.setState(2);
				
				operationWorkHandleDao.save(shiftHandle);
				
				StringBuffer handlers = new StringBuffer(work.getHandlers());
				handlers.append(shiftHandler.getUserName()).append(";");
				work.setHandlers(handlers.toString());
				operationWorkDao.update(work);
				
				messageCreator.sentToUserWhenWorkShift(work.getUsername(), shiftHandler);
				messageCreator.sentToEngineerWhenWorkDistribute(shiftHandler.getUserId(), work);
	    		
			}else if(handle.getState() == 2){
				operationWorkDao.update(work);
			}else{
				//挂起或完成
				Integer workState = getWorkState(workId);
				if(workState != 2){
					work.setState(workState);
					work.setEndTime(DateUtil.getInstance().todayShort());
					operationWorkDao.update(work);
					if(workState == 3){
						//挂起
						messageCreator.sentToUserWhenWorkHangUp(work.getUsername(), handler);
					}else{
						//完成
						MailUtil.getInstance().sentWhenWorkFinished(work.getEmail());
						messageCreator.sentToUserWhenWorkFinish(work.getUsername());
					}
					
				}
			}
		}else{
			throw new Exception("此工作你没有权限操作！");
		}
	}
	
	/**
	 * 获取工作的处理状态
	 * @param workId
	 * @return
	 */
	private Integer getWorkState(Integer workId){
		List<OperationWorkHandle> allHandles = operationWorkHandleDao.findByWorkId(workId);
		Integer state = 4;
		for(OperationWorkHandle h : allHandles){
			if(h.getState() == 2){
				state = 2;
				break;
			}else if(h.getState() == 3){
				state = 3;
			}else  if(h.getState() == 4){
				continue;
			}
		}
		
		return state;
	}
	/**
	 * 获取简单的统计数据
	 * @param user
	 * @return
	 * @throws Exception
	 */
	@Override
	public String getSimpleStatistics(User user) throws Exception{
	
		StringBuffer sql = new StringBuffer("select ");
		sql.append("sum(case when t.state = 1 then 1 else 0 end)  notHandle,");
		sql.append("sum(case when t.state = 2 then 1 else 0 end)  handling,");
		sql.append("sum(case when t.state = 3 then 1 else 0 end)  handup,");
		sql.append("sum(case when t.state = 4 then 1 else 0 end)  handled,");
		sql.append("sum(case when t.state = 5 then 1 else 0 end)  feedback\n");
		sql.append("from operation_work t\n ");
		if(user.getAuthority().isPersonal(Constant.MODULE_OPERATION_WORK)){
			sql.append("where t.id in(select d.upId from operation_work_handle d where d.username='").append(user.getUserId()).append("')");
		}
		List<Map> list = operationWorkDao.listBySQL(sql.toString());
		return JSONHelper.convertToGrid(Long.valueOf(1), list);
	}
	
	/**
	 * 下拉加载分页数据
	 * findWhenLoad
	 * 
	 * @param user
	 * @param page
	 * @param pageSize
	 * @param state
	 * @param type 
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public String findWhenLoad(User user, Integer page, Integer pageSize,Integer state, Integer type) {
		StringBuffer hql = new StringBuffer("from OperationWork work where 1=1 and work.state<>0");
		hql.append(createConditionHQLToWX(user, state));
		
		if(type != null && (type == 1 || type == 2)){
			//报修人员
			if(type == 1){
				hql.append("  and (work.state<>4 and work.state<>5) ");
			}else{
				hql.append("  and (work.state=4 or work.state=5) ");
			}
		}
		
		Integer start = (page-1)*pageSize;
		
		List<OperationWork> list = operationWorkDao.pageByHQL(hql.toString(), start, pageSize);
		
		Long total = operationWorkDao.getTotalByHQL(hql.toString());
		return JSONHelper.convertToGrid(total, list);
	}

	/**
	 * 获取处理过程
	 * findWorkHandles
	 * 
	 * @param workId
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public List<OperationWorkHandle> findWorkHandles(Integer workId){
		StringBuffer hql = new StringBuffer("from OperationWorkHandle t where 1=1 ");

		hql.append("and t.operationWork.id=").append(workId);
		
		return operationWorkHandleDao.findByHql(hql.toString());
	}
	
	
	/**
	 * 根据ID获取工作
	 * findWorkById
	 * 
	 * @param id
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public OperationWork findWorkById(Integer id) {
		OperationWork work = operationWorkDao.findById(id);
		if(work.getDevice() != null){
			GrgemEquipments equipment = equipmentDao.findById(work.getDevice());
			work.setEquipment(equipment);
		}
		return work;
	}
	/**
	 * 根据用户为最新处理完的工作进行评价
	 * updateWhenFeedback
	 * 
	 * @param username
	 * @param feedbackGrade 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public OperationWork updateWhenFeedback(String username, Integer feedbackGrade) {
		OperationWork work = null;
		StringBuffer hql = new StringBuffer("from OperationWork work where work.state=4 ");
		hql.append("and work.username='").append(username).append("' order by work.id desc");
		List<OperationWork> works =  operationWorkDao.findByHql(hql.toString());
		if(works.size() > 0){
			work = works.get(0);
			work.setFeedbackGrade(getFreebackGrade(feedbackGrade));
			work.setState(5);
			operationWorkDao.update(work);
		}
		
		return work;
	}

	/**
	 * 获取反馈级别
	 * getFreebackGrade
	 * 
	 * @param feedbackGrade
	 * @return 
	 * @exception 
	 * @since  1.0.0
	 */
	private Integer getFreebackGrade(Integer feedbackGrade) {
		if(feedbackGrade < 1){
			feedbackGrade = 1;
		}else if(feedbackGrade > 4){
			feedbackGrade = 4;
		}
		return feedbackGrade;
	}
	
	
	/**
	 * 获取回复的信息
	 * getMessageWhenRecived
	 * 
	 * @param username
	 * @param type  1工作创建时,2工作评价成功,3工作评价失败
	 * @return
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public String getMessageWhenRecived(String username ,WXVerify verify, Integer type)
			throws Exception {
		String msg = null;
		if(type == 1){
			//回复工作创建信息
			msg = messageCreator.getWhenWorkFromMenu(username,verify.getTimestamp(),verify.getNonce());
		}else if(type == 2){
			//工作评价成功
			msg = messageCreator.getWhenWorkFeedback(username,verify.getTimestamp(),verify.getNonce(),true);
		}else if(type == 3){
			//工作评价失败
			msg = messageCreator.getWhenWorkFeedback(username,verify.getTimestamp(),verify.getNonce(),false);
		}
		return msg;
	}
	
	/**
	 * 生成HQL条件语句
	 * @param user
	 * @param username
	 * @param states
	 * @return
	 */
	private StringBuffer createConditionHQL(User user, String username,
			Integer[] states) {
		
		StringBuffer hql = new StringBuffer();
		
		if(user.getAuthority().isCommon(Constant.MODULE_OPERATION_WORK)){
			//普通用户权限
			hql.append(" and (work.trueName like '%").append(user.getUserId())
			   .append("%' or work.username like '%").append(user.getUserId()).append("%')");
		}else if(user.getAuthority().isPersonal(Constant.MODULE_OPERATION_WORK)){
			//工程师权限
			hql.append(" and work.id in(select handle.operationWork.id from OperationWorkHandle handle where 1=1");

			hql.append(" and handle.username='").append(user.getUserId()).append("')");
			hql.append(" or work.creator='").append(user.getUserId()).append("'");
		}
		
		if(StringUtils.isNotEmpty(username)){
			hql.append(" and (work.trueName like '%").append(username)
				.append("%' or work.username like '%").append(username).append("%')");
		}
		
		if(states != null ){
			hql.append(HibernateUtil.convertToIN(states, "work.state"));
		}
		
		return hql;
	}
	
	/**
	 * 生成HQL条件语句(微信)
	 * @param user
	 * @param state
	 * @return
	 */
	private StringBuffer createConditionHQLToWX(User user,
			Integer state) {
		
		StringBuffer hql = new StringBuffer();

		if(user.getAuthority().isCommon(Constant.MODULE_OPERATION_WORK)){
			//普通用户权限
			hql.append(" and (work.trueName like '%").append(user.getUserId())
			.append("%' or work.username like '%").append(user.getUserId()).append("%')");
		}else if(user.getAuthority().isPersonal(Constant.MODULE_OPERATION_WORK)){
			//工程师权限
			hql.append(" and work.id in(select handle.operationWork.id from OperationWorkHandle handle where 1=1");
			
			hql.append(" and handle.state=").append(state);
			hql.append(" and handle.username='").append(user.getUserId()).append("')");
			if(state == 1){
				hql.append(" or work.creator='").append(user.getUserId()).append("'");
			}	
		}else{
			//全局权限
			if(state != -1 ){
				if( state == 4){
					hql.append(" and (work.state=4  or work.state=5)");
				}else{
					hql.append(" and work.state=").append(state);
				}
			}	
		}

		return hql;
	}
	/**
	 * 导出数据
	 * export
	 * 
	 * @param operationWork
	 * @param user
	 * @param exportParams
	 * @return
	 * @throws Exception 
	 * @exception 
	 * @since  1.0.0
	 */
	@Override
	public HSSFWorkbook getExtportBook(OperationWork operationWork, User user,
			String exportParams) throws Exception {
		String hql = this.createQueryHQL(operationWork, user).toString();
		List<OperationWork> works = operationWorkDao.findByHql(hql);
		return poiCreator.createOneSheetBook("运维工作查询结果", works, exportParams);
	}

	
}